package com.gton.controller;


import cn.dev33.satoken.util.SaResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gton.config.common.ContextCommonMsg;
import com.gton.config.common.NeedTokenByJWT;
import com.gton.config.common.RedisLock;
import com.gton.entity.AuthLoginUser;
import com.gton.service.AuthLoginUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author GuoTong
 * @since 2022-11-27
 */
@RestController
@RequestMapping("/authLoginUser")
@Api(tags = "认证中心用户管理")
@Slf4j
public class AuthLoginUserController {


    @Autowired
    private AuthLoginUserService authLoginUserService;

    @Autowired
    private RedisLock redisLock;


    @PostMapping(value = "/save", name = "新增用户")
    @ApiOperation(value = "认证中心用户管理 ->新增用户", notes = "insomnia测试")
    public SaResult save(@RequestBody AuthLoginUser authLoginUser) {
        try {
            // 名字已被占用的不能注册
            boolean isExist = authLoginUserService.queryUserNameIsExist(authLoginUser.getUsername());
            if (!isExist) {
                return SaResult.error(ContextCommonMsg.ERROR_MSG_7);
            }
            authLoginUserService.save(authLoginUser);
        } catch (Exception e) {
            log.error(e.getMessage());
            return SaResult.error(e.getMessage());
        }
        return SaResult.ok(authLoginUser.getUsername());
    }


    @GetMapping(value = "/queryOne", name = "查询")
    @ApiOperation(value = "认证中心用户管理 ->查询", notes = "insomnia测试")
    public SaResult query(@RequestParam("keywords") String keywords) {
        if (StringUtils.isNotEmpty(keywords)) {
            QueryWrapper<AuthLoginUser> wrapper = new QueryWrapper<>();
            String[] keys = keywords.split("&");
            for (String key : keys) {
                if (key.contains("username")) {
                    wrapper.like("username", key.split("=")[1]);
                }
                if (key.contains("id=")) {
                    wrapper.eq("id", key.split("=")[1]);
                }
            }
            if (keys.length >= 1) {
                List<AuthLoginUser> list = authLoginUserService.list(wrapper);
                return SaResult.data(list);
            }
        }
        return SaResult.error(ContextCommonMsg.ERROR_MSG_2);
    }


    @PutMapping(value = "/update", name = "修改用户")
    @ApiOperation(value = "认证中心用户管理 ->修改用户", notes = "insomnia测试")
    @NeedTokenByJWT(rule = "ADMIN")
    public SaResult update(@RequestBody AuthLoginUser authLoginUser) {
        if (authLoginUser.getId() <= 0) {
            return SaResult.error(ContextCommonMsg.ID_ERROR_MSG);
        }
        String redisLockKey = authLoginUser.getId() + authLoginUser.getUsername();
        // 校验当前Id和用户是否是同一人:使用Redis分布式锁
        boolean getLockStatus = redisLock.tryGetLock(redisLockKey);
        String errorMsg = ContextCommonMsg.ERROR_MSG_0;
        if (getLockStatus) {
            try {
                // 先查询ID号和用户是否是同一组数据，防止串改
                AuthLoginUser thisUser = authLoginUserService.getById(authLoginUser.getId());
                if (StringUtils.equals(thisUser.getUsername(), authLoginUser.getUsername())) {
                    authLoginUserService.updateById(authLoginUser);
                    // 释放Redis锁
                    redisLock.shutdownLock(redisLockKey);
                    return SaResult.ok(authLoginUser.getUsername());
                }
                errorMsg = ContextCommonMsg.ERROR_MSG_1;
            } catch (Exception e) {
                log.error(e.getMessage());
                errorMsg = e.getMessage();

            }
        }
        return SaResult.error(errorMsg);
    }
}

